package com.shawn.dubbo.api;

import com.shawn.model.mongo.Sound;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;
import java.util.Objects;

/**
 * @author shawn
 * @date 2022年 11月 11日 19:43
 */

@DubboService
public class PeachVoiceApiImpl implements PeachVoiceApi{

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 发布声音
     *
     * @param sound 声音
     * @return {@link String}
     */
    @Override
    public String save(Sound sound) {
        Sound sou = mongoTemplate.save(sound);
        return sou.getId().toHexString();
    }

    /**
     * 得到随机声音
     *
     * @param userId   用户id
     * @param voiceIds ids声音
     * @return {@link Sound}
     */
    @Override
    public Sound getRandomVoice(Long userId ,List<ObjectId> voiceIds) {
        TypedAggregation<Sound> aggregation;
        if (!Objects.isNull(voiceIds)) {
             aggregation = TypedAggregation.newAggregation(
                    Sound.class,
                    Aggregation.sample(1),
                    Aggregation.match(Criteria.where("userId").ne(userId)),//不听自己
                    Aggregation.match(Criteria.where("id").not().in(voiceIds)),//不听已经听过
                    Aggregation.match(Criteria.where("remainingTimes").gt(0))//不听已经没有次数的
            );
        }else {
            aggregation = TypedAggregation.newAggregation(
                    Sound.class,
                    Aggregation.sample(1),
                    Aggregation.match(Criteria.where("userId").ne(userId)),
                    Aggregation.match(Criteria.where("remainingTimes").ne(0))
            );
        }
        AggregationResults<Sound> aggregate = mongoTemplate.aggregate(aggregation, Sound.class);
        List<Sound> sounds = aggregate.getMappedResults();
        Sound sound =sounds.size()==0?null:sounds.get(0);
        if (!Objects.isNull(sound)){
            //如果取出的语音不为空则,则语音可取次数减一
            Query query = new Query(Criteria.where("id").is(sound.getId()));
            Update update = new Update();
            update.inc("remainingTimes",-1);
            mongoTemplate.updateFirst(query,update,Sound.class);
        }
        return sound;
    }
}
